﻿// 功能：扩展图片框
// 描述：
// 作者：温伟鹏
// 日期：2010/5/20 23:01:12

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.IO;

namespace MeizuSDK.Presentation
{
    /// <summary>
    /// 扩展图片框（）
    /// </summary>
    public class PictureBoxEx : Control
    {
        #region DllImport
        [DllImport("MZFCWrapper.dll")]
        private static extern IntPtr UiStaticWrapperCtor(PaintWinFunc pPaintWin);
        #endregion

        #region 私有变量
        private Image bgImage;// 背景图片
        private Image bufferImage;// 进行处理过的背景缓存图片
        private PictureBoxSizeMode sizeMode;// 图片定位
        private string imageLocation;// 图片路径
        #endregion

        #region 公共属性
        /// <summary>
        /// 获取或设置控件显示的图片
        /// </summary>
        public Image Image
        {
            get
            {
                return this.bgImage;
            }
            set
            {
                if (value != bgImage)
                {
                    bgImage = value;
                    // 更新缓存图片，并重绘
                    BufferImage = value;
                }
            }
        }
        /// <summary>
        /// 获取或设置控件显示图片的路径
        /// </summary>
        public string ImageLocation
        {
            get
            {
                return imageLocation;
            }
            set
            {
                if (value != this.imageLocation)
                {
                    LoadImage(value);
                }
            }
        }
        /// <summary>
        /// 获取或设置经过缩放处理的显示图片
        /// </summary>
        protected Image BufferImage
        {
            get
            {
                return this.bufferImage;
            }
            set
            {
                if (value != this.bufferImage)
                {
                    if(this.bufferImage!=null)
                    {
                        this.bufferImage.Dispose();
                    }

                    if (value == null)
                    {
                        this.bufferImage = null;
                        return;
                    }

                    this.bufferImage = new Bitmap(Width, Height);

                    Rectangle imgRect = Rectangle.Empty;
                    Rectangle clientRect = Rectangle.Empty;
                    int imgWidth = 0;
                    int imgHeight = 0;

                    using (Graphics g = Graphics.FromImage(this.bufferImage))
                    {
                        switch (SizeMode)
                        {
                            case PictureBoxSizeMode.StretchImage:
                                imgRect = new Rectangle(0, 0, Image.Width, Image.Height);
                                break;
                            case PictureBoxSizeMode.Normal:
                                imgRect = new Rectangle(0, 0, Width, Height);
                                g.DrawImage(Image, ClientRectangle, imgRect, GraphicsUnit.Pixel);
                                break;
                            case PictureBoxSizeMode.CenterImage:
                                clientRect = new Rectangle((Width - Image.Width) / 2, (Height - Image.Height) / 2, Image.Width, Image.Height);
                                imgRect = new Rectangle(0, 0, Image.Width, Image.Height);
                                break;
                            case PictureBoxSizeMode.Zoom:
                                imgRect = new Rectangle(0, 0, Image.Width, Image.Height);

                                if (Image.Width > Image.Height)
                                {
                                    imgWidth = Width;
                                    imgHeight = (int)(Image.Height * ((Image.Width >= Width) ? ((float)Width / (float)Image.Width) : ((float)Image.Width / (float)Width)));

                                    clientRect = new Rectangle(0, (Height - imgHeight) / 2, imgWidth, imgHeight);
                                }
                                else if (Image.Width < Image.Height)
                                {
                                    imgHeight = Height;
                                    imgWidth = (int)(Image.Width * ((Image.Height >= Height) ? ((float)Height / (float)Image.Height) : ((float)Image.Height / (float)Height)));

                                    clientRect = new Rectangle((Width - imgWidth) / 2, 0, imgWidth, imgHeight);
                                }
                                else
                                {
                                    clientRect = new Rectangle(0, 0, Width, Height);
                                }

                                break;
                        }

                        g.DrawImage(Image, clientRect, imgRect, GraphicsUnit.Pixel);
                    }

                    Invalidate();
                    Update();
                }
            }
        }
        /// <summary>
        /// 获取或设置图片在控件中的定位方式
        /// </summary>
        public PictureBoxSizeMode SizeMode
        {
            get
            {
                return this.sizeMode;
            }
            set
            {
                if (value != this.sizeMode)
                {
                    this.sizeMode = value;

                    // 更新缓存图片，并重绘
                    BufferImage = Image;
                }
            }
        }
        #endregion

        #region 构造函数
        public PictureBoxEx()
        {
            Handle = UiStaticWrapperCtor(PaintWinDelegate);
            SetID();
        }
        #endregion

        #region 函数
        /// <summary>
        /// 图片框大小被改变事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnSizeChanged(EventArgs e)
        {
            // 大小改变后，重设缓存图片
            BufferImage = Image;

            base.OnSizeChanged(e);
        }
        /// <summary>
        /// 根据指定路径加载图片
        /// </summary>
        /// <param name="imgPath">图片文件所在路径</param>
        private void LoadImage(string imgPath)
        {
            if (File.Exists(imgPath))
            {
                this.imageLocation = imgPath;

                Image = new Bitmap(imgPath);
            }
            else
            {
                this.imageLocation = string.Empty;
            }
        }
        /// <summary>
        /// 控件重绘
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaintWin(PaintEventArgs e)
        {
            // 这里使用已经进行处理的缓存背景图片进行绘图

            if (this.BufferImage == null)
                return;

            e.Graphics.DrawImage(BufferImage, e.UpdateRectangle, e.UpdateRectangle, GraphicsUnit.Pixel);

            base.OnPaintWin(e);
        }
        /// <summary>
        /// 销毁资源
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            if(disposing)
            {
                if(BufferImage!=null)
                {
                    BufferImage.Dispose();
                }
                if(Image!=null)
                {
                    Image.Dispose();
                }
            }
            base.Dispose(disposing);
        }
        #endregion
    }
}
